using System;
using System.Threading;
using System.Threading.Tasks;

namespace RTMP.SimpleClient.Callbacks
{
    /// <summary>
    /// 强类型消息回调接口
    /// </summary>
    /// <typeparam name="T">消息类型</typeparam>
    public interface IMessageCallback<in T> where T : class
    {
        /// <summary>
        /// 处理消息
        /// </summary>
        /// <param name="message">强类型消息对象</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>处理任务</returns>
        Task HandleAsync(T message, CancellationToken cancellationToken = default);
    }

    /// <summary>
    /// 基于委托的消息回调实现
    /// </summary>
    /// <typeparam name="T">消息类型</typeparam>
    public class DelegateMessageCallback<T> : IMessageCallback<T> where T : class
    {
        private readonly Func<T, CancellationToken, Task> _handler;

        public DelegateMessageCallback(Func<T, CancellationToken, Task> handler)
        {
            _handler = handler ?? throw new ArgumentNullException(nameof(handler));
        }

        public DelegateMessageCallback(Func<T, Task> handler)
        {
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            _handler = (message, _) => handler(message);
        }

        public DelegateMessageCallback(Action<T> handler)
        {
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            _handler = (message, _) => 
            {
                handler(message);
                return Task.CompletedTask;
            };
        }

        public Task HandleAsync(T message, CancellationToken cancellationToken = default)
        {
            return _handler(message, cancellationToken);
        }
    }

    /// <summary>
    /// 消息回调注册信息
    /// </summary>
    public class CallbackRegistration
    {
        /// <summary>
        /// 回调键
        /// </summary>
        public CallbackKey Key { get; set; }

        /// <summary>
        /// 回调处理器
        /// </summary>
        public object Handler { get; set; } = null!;

        /// <summary>
        /// 消息类型
        /// </summary>
        public Type MessageType { get; set; } = null!;

        /// <summary>
        /// 是否为一次性回调
        /// </summary>
        public bool IsOneTime { get; set; }

        /// <summary>
        /// 超时时间（可选）
        /// </summary>
        public TimeSpan? Timeout { get; set; }

        /// <summary>
        /// 注册时间
        /// </summary>
        public DateTime RegisteredAt { get; set; } = DateTime.UtcNow;
    }
}